﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Utility.Math
{
	public static class BitOperation
	{
		public static int CreateMask (int startPos, int length)
		{
			return ((1 << length) - 1) << startPos;
		}

		public static string ToBitString (this int x)
		{
			return System.Convert.ToString (x, 2);
		}

		public static int ClearBit (this int x, int pos)
		{
			return x & ~(1 << pos);
		}

		public static int ToggleBit (this int x, int pos)
		{
			return x ^ (1 << pos);
		}

		public static int SetBit (this int x, int pos)
		{
			return x | (1 << pos);
		}

		public static int SetBit (this int x, int pos, bool bit)
		{
			return bit ? SetBit (x, pos) : ClearBit (x, pos);
		}

		public static int SetBits (this int x, int startPos, int length, int bits)
		{
			int mask = CreateMask (startPos, length);
			x &= ~mask;
			bits &= mask;
			return x | bits;
		}

		public static int TakeBit (this int x, int pos)
		{
			return x & (1 << pos);
		}

		public static int TakeBits (this int x, int startPos, int length)
		{
			return x & CreateMask (startPos, length);
		}

		public static bool CheckBit (this int x, int pos)
		{
			return TakeBit (x, pos) > 0;
		}

		public static bool CheckBit (this int x, int pos, bool bit)
		{
			return CheckBit (x, pos) ^ !bit;
		}

		public static int RotateRight (this int x, int startPos, int length, int count)
		{
			count = count % length;
			int mask = CreateMask (startPos, length);
			int bits = x & mask;
			bits = (bits >> count) | (bits << length - count);
			bits &= mask;
			x &= ~mask;
			return x | bits;
		}

		public static int RotateLeft (this int x, int startPos, int length, int count)
		{
			count = count % length;
			int mask = CreateMask (startPos, length);
			int bits = x & mask;
			bits = (bits << count) | (bits >> length - count);
			bits &= mask;
			x &= ~mask;
			return x | bits;
		}
	}
}